package com.duolebo.uteped_sdk.utils;

import android.Manifest;
import android.app.Activity;
import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.provider.Settings;

import androidx.core.app.ActivityCompat;

import com.tbruyelle.rxpermissions.RxPermissions;

import java.util.HashMap;
import java.util.Map;

import rx.functions.Action1;

/**
 * @Author: LiuYang
 * @Date: 2023/12/12 14:23
 * @Description: 权限检测
 */
public class PermissionHelper {

    private static final String MANUFACTURER_HUAWEI = "HUAWEI"; //华为
    private static final String MANUFACTURER_MEIZU = "Meizu"; //魅族
    private static final String MANUFACTURER_XIAOMI = "Xiaomi"; //小米
    private static final String MANUFACTURER_SONY = "Sony"; //索尼
    private static final String MANUFACTURER_OPPO = "OPPO"; //oppo
    private static final String MANUFACTURER_LG = "LG";
    private static final String MANUFACTURER_VIVO = "vivo"; //vivo

    private static final String[] P_BT_GROUP = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
    };

    private static final String[] P_BT_GROUP_SDK_31 = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            "android.permission.BLUETOOTH_SCAN",
            "android.permission.BLUETOOTH_CONNECT"
    };

    private static final String[] P_CALL_GROUP = new String[]{
        Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.READ_CALL_LOG,
    };

    private static final String[] P_CALL_GROUP_SDK_26 = new String[]{
            Manifest.permission.READ_PHONE_STATE,
            "android.permission.READ_PHONE_NUMBERS",
            Manifest.permission.READ_CALL_LOG,
            Manifest.permission.READ_CONTACTS //电话号码对应名字需要读取通讯录
    };

    private static final String[] P_SMS_GROUP = new String[]{
            Manifest.permission.RECEIVE_SMS,
            Manifest.permission.READ_SMS,
            Manifest.permission.SEND_SMS
    };

    private static final String[] P_LOCATION_GROUP = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
    };

    private static final String[] P_CONTACT_GROUP = new String[]{
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.GET_ACCOUNTS
    };

    private static final String[] P_STORAGE_GROUP = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    private static final String[] P_UPGRADE_GROUP = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.READ_PHONE_STATE,
    };

    private static final Map<String, String[]> permissionMap = new HashMap<>();

    private static PermissionHelper instance;
    public static PermissionHelper getInstance() {
        if (instance == null) {
            instance = new PermissionHelper();
        }

        return instance;
    }

    public PermissionHelper() {
        initPermissionMap();
    }

    private void initPermissionMap() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            permissionMap.put(Const.P_bluetooth, P_BT_GROUP_SDK_31);
        }
        else {
            permissionMap.put(Const.P_bluetooth, P_BT_GROUP);
        }

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            permissionMap.put(Const.P_call, P_CALL_GROUP_SDK_26);
        }
        else {
            permissionMap.put(Const.P_call, P_CALL_GROUP);
        }

        permissionMap.put(Const.P_contact, P_CONTACT_GROUP);
        permissionMap.put(Const.P_location, P_LOCATION_GROUP);
        permissionMap.put(Const.P_sms, P_SMS_GROUP);
        permissionMap.put(Const.P_upgrade, P_UPGRADE_GROUP);
    }

    /**
     * 蓝牙权限检测
     * @param activity activity
     * @param action1 action1
     */
    public void checkBluetoothPermissions(Activity activity, Action1<Boolean> action1) {
        String[] permissions = P_BT_GROUP;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            //把BLUETOOTH_CONNECT也申请了，因为搜索出来时需要获取蓝牙名称来显示，而获取蓝牙名称需要用到这个权限
            permissions = P_BT_GROUP_SDK_31;
        }
        new RxPermissions(activity).request(permissions).subscribe(action1);
    }

    public void checkLocationPermissions(Activity activity, Action1<Boolean> action1) {
        new RxPermissions(activity).request(P_LOCATION_GROUP).subscribe(action1);
    }

    public void checkSmsPermissions(Activity activity, Action1<Boolean> action1) {
        new RxPermissions(activity).request(P_SMS_GROUP).subscribe(action1);
    }

    public void checkCallPermissions(Activity activity, Action1<Boolean> action1) {
        String[] permissions = P_CALL_GROUP;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            permissions = P_CALL_GROUP_SDK_26;
        }
        new RxPermissions(activity).request(permissions).subscribe(action1);
    }

    /**
     * 通讯录权限请求
     * @param activity activity
     * @param action1 action1
     */
    public void checkContactPermissions(Activity activity, Action1<Boolean> action1) {
        new RxPermissions(activity).request(P_CONTACT_GROUP).subscribe(action1);
    }

    public void checkStoragePermission(Activity activity, Action1<Boolean> action1) {
        new RxPermissions(activity).request(P_STORAGE_GROUP).subscribe(action1);
    }

    public void checkUpgradePermission(Activity activity, Action1<Boolean> action1) {
        new RxPermissions(activity).request(P_UPGRADE_GROUP).subscribe(action1);
    }

    public void checkPermission(Activity activity, String permission, Action1<Boolean> action1) {
        new RxPermissions(activity).request(permission).subscribe(action1);
    }

    public static boolean hasBluetoothPermissions() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
            return hasPermission(P_BT_GROUP_SDK_31);
        }
        else {
            return hasPermission(P_BT_GROUP);
        }
    }

    public static boolean hasCallPermissions() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            return hasPermission(P_CALL_GROUP_SDK_26);
        }
        else {
            return hasPermission(P_CALL_GROUP);
        }
    }

    public static boolean hasUpgradePermissions() {
        return hasPermission(P_UPGRADE_GROUP);
    }

    public static boolean hasSmsPermissions() {
        return hasPermission(P_SMS_GROUP);
    }

    public static boolean hasLocationPermissions() {
        return hasPermission(P_LOCATION_GROUP);
    }

    public static boolean hasContactPermissions() {
        return hasPermission(P_CONTACT_GROUP);
    }

    public static boolean hasStoragePermissions() {
        return hasPermission(P_STORAGE_GROUP);
    }

    public static boolean hasPermission(String permission) {
        boolean result = false;
        if (permission.startsWith("p_")) {
            if (permissionMap.containsKey(permission)) {
                result = hasPermission(permissionMap.get(permission));
            }
        }
        else {
            result = hasPermission(new String[]{permission});
        }

        return result;
    }

    public static boolean hasAppOpsPermission() {
        Context context = Tools.getApplicationContext();
        boolean granted = false;
        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
                Process.myUid(), context.getPackageName());
        if (mode == AppOpsManager.MODE_DEFAULT) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                granted = (context.checkCallingOrSelfPermission(Manifest.permission.PACKAGE_USAGE_STATS) == PackageManager.PERMISSION_GRANTED);
            }
        } else {
            granted = (mode == AppOpsManager.MODE_ALLOWED);
        }
        return granted;
    }

    public static void toAppOpsPage() {
        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Tools.getApplicationContext().startActivity(intent);
    }

    private static boolean hasPermission(String[] permissions) {
        boolean granted = true;
        for (String permission:permissions) {
            if (ActivityCompat.checkSelfPermission(Tools.getApplicationContext(), permission) != PackageManager.PERMISSION_GRANTED) {
                granted = false;
                break;
            }
        }

        return granted;
    }

    public static void toMyAppPermissionSetting(Context context) {
        toDefaultPermissionSetting(context, context.getPackageName());
    }

    /**
     * toPermissionSetting
     * @param context context
     * @param packageName packageName
     * @return result
     */
    public static void toPermissionSetting(Context context, String packageName) {
        switch (Build.MANUFACTURER) {
            case MANUFACTURER_HUAWEI:
                toHuaweiPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_MEIZU:
                toMeizuPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_XIAOMI:
                toXiaomiPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_SONY:
                toSonyPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_OPPO:
                toOPPOPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_LG:
                toLGPermissionSetting(context, packageName);
                break;
            case MANUFACTURER_VIVO:
                toVivoPermissionSetting(context, packageName);
                break;
            default:
                toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toHuaweiPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("packageName", packageName);
            ComponentName comp = new ComponentName(
                    "com.huawei.systemmanager",
                    "com.huawei.permissionmanager.ui.MainActivity"
            );
            intent.setComponent(comp);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toMeizuPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.putExtra("packageName", packageName);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toXiaomiPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            intent.putExtra("extra_pkgname", packageName);
            ComponentName componentName = new ComponentName(
                    "com.miui.securitycenter",
                    "com.miui.permcenter.permissions.PermissionsEditorActivity"
            );
            intent.setComponent(componentName);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toSonyPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("packageName", packageName);
            ComponentName comp = new ComponentName(
                    "com.sonymobile.cta",
                    "com.sonymobile.cta.SomcCTAMainActivity"
            );
            intent.setComponent(comp);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toOPPOPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("packageName", packageName);
            // ComponentName comp = new ComponentName("com.color.safecenter", "com.color.safecenter.permission.PermissionManagerActivity");
            ComponentName comp = new ComponentName(
                    "com.coloros.securitypermission",
                    "com.coloros.securitypermission.permission.PermissionAppAllPermissionActivity"
            ); //R11t 7.1.1 os-v3.2
            intent.setComponent(comp);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toLGPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent("android.intent.action.MAIN");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("packageName", packageName);
            ComponentName comp = new ComponentName(
                    "com.android.settings",
                    "com.android.settings.Settings$AccessLockSummaryActivity"
            );
            intent.setComponent(comp);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    public static void toVivoPermissionSetting(Context context, String packageName) {
        try {
            Intent intent = new Intent("android.intent.action.MAIN");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("packageName", packageName);
            ComponentName comp = new ComponentName(
                    "com.android.settings",
                    "com.vivo.permissionmanager.activity.PurviewTabActivity"
            );
            intent.setComponent(comp);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            toDefaultPermissionSetting(context, packageName);
        }
    }

    /**
     * 默认打开应用详细页
     */
    private static void toDefaultPermissionSetting(Context context, String packageName) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri uri = Uri.fromParts("package", packageName, null);
        intent.setData(uri);
        try {
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
